home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Workbench Add-On
/
Workbench Add-On - Volume 1.iso
/
Dev
/
SmallTalk
/
mstcint.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-08-25
|
25KB
|
1,103 lines
/***********************************************************************
*
* C - Smalltalk Interface module
*
***********************************************************************/
/***********************************************************************
*
* Copyright (C) 1990, 1991, 1992 Free Software Foundation, Inc.
* Written by Steve Byrne.
*
* This file is part of GNU Smalltalk.
*
* GNU Smalltalk is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 1, or (at your option) any later
* version.
*
* GNU Smalltalk is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* GNU Smalltalk; see the file COPYING. If not, write to the Free Software
* Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
***********************************************************************/
/*
* Change Log
* ============================================================================
* Author Date Change
* sbb 23 Feb 92 Added support for reading and writing scalar types.
*
* sbb 19 Jul 91 Started adding support for the DLD package.
*
* sbb 22 Jan 91 Added putenv().
*
* sbb 17 Nov 90 Added support for UnixStream primitives.
*
* sbb 11 Aug 90 Added knowledge of byteArrayOut type.
*
* sbyrne 4 Jun 89 Added Smalltalk data conversion type.
*
* sbyrne 29 May 89 Created.
*
*/
/* Define this to enable initialization of the SunView hacks in the
./examples directory */
/* #define SUN_WIN_HACKS */
#include "mst.h"
#include "mstinterp.h"
#include "mstdict.h"
#include "mstoop.h"
#include "mstsym.h"
#include "mstcallin.h"
#define ARG_VEC_SIZE 20 /* 20 ints, 10 longs or ptrs, 5 dbls */
typedef enum {
intAlign,
longAlign,
ptrAlign,
doubleAlign
} AlignmentType;
typedef enum { /* types for C parameters */
unknownType, /* when there is no type a priori */
charType,
stringType,
stringOutType, /* for things that modify string params */
symbolType,
byteArrayType,
byteArrayOutType,
intType,
longType,
doubleType,
voidType, /* valid only as a return type */
variadicType, /* for parameters, this param is an array
to be interpreted as arguments. Note that
only simple conversions are performed in
this case. */
cObjectType, /* a C object is being passed */
smalltalkType /* no conversion to-from C...C sees this
as "void *". */
} CDataType;
typedef struct CFuncDescriptorStruct {
OBJ_HEADER;
OOP cFunction;
OOP cFunctionName;
OOP returnType;
OOP numFixedArgs;
OOP argTypes[1]; /* variable length, really numFixedArgs long */
} *CFuncDescriptor;
typedef struct SymbolTypeMapStruct {
OOP *symbol;
CDataType type;
} SymbolTypeMap;
typedef struct StringInfoStruct {
Byte *cString;
OOP stringOOP;
CDataType returnedType;
} StringInfo;
typedef union CParamUnionUnion {
int intVal;
long longVal;
voidPtr ptrVal;
double doubleVal;
int valueVec[sizeof(double) / sizeof(int)];
} CParamUnion;
typedef struct CFuncInfoStruct {
char *funcName;
void (*funcAddr)();
} CFuncInfo;
extern int errno;
void defineCFunc();
static void pushObj(), callCFunction(),
badType(), pushSmalltalkObj();
static CDataType getCType();
static CFuncDescriptor getCFuncDescriptor();
static OOP classifyTypeSymbol();
static int savedErrno;
static OOP readChar();
static OOP readUChar();
static OOP readShort();
static OOP readUShort();
static OOP readLong();
static OOP readULong();
static OOP readFloat();
static OOP readDouble();
static void writeChar();
static void writeShort();
static void writeLong();
static void writeFloat();
static void writeDouble();
static CFuncInfo cFuncInfo[100], *cFuncIndex = cFuncInfo;
static int cArgVec[ARG_VEC_SIZE];
static int *cArg;
static StringInfo stringInfo[ARG_VEC_SIZE], *sip;
/* printable names for corresponding C types */
static char *cTypeName[] = {
"void?", /* unknownType */
"char", /* charType */
"char *", /* stringType */
"char *", /* stringOutType */
"char *", /* symbolType */
"char *", /* byteArrayType */
"char *", /* byteArrayOutType */
"int", /* intType */
"long", /* longType */
"double", /* doubleType */
"void?", /* voidType */
"var args?", /* variadicType */
"void *", /* cObjectType */
"void *", /* smalltalkType */
};
static SymbolTypeMap symbolTypeMap[] = {
&unknownSymbol, unknownType,
&charSymbol, charType,
&stringSymbol, stringType,
&stringOutSymbol, stringOutType,
&symbolSymbol, symbolType,
&byteArraySymbol, byteArrayType,
&byteArrayOutSymbol, byteArrayOutType,
&intSymbol, intType,
&longSymbol, longType,
&doubleSymbol, doubleType,
&voidSymbol, voidType,
&variadicSymbol, variadicType,
&cObjectSymbol, cObjectType,
&smalltalkSymbol, smalltalkType,
nil, unknownType
};
/* the arg vec pointer must be = 0 mod alignments[align] */
/* This is quite likely to be machine dependent. Currently it is set up
* to work correctly on sun2's, sun3's and sun4's */
static int alignments[] = {
sizeof(int), /* intType */
sizeof(long), /* longType */
sizeof(voidPtr), /* ptrType */
DOUBLE_ALIGNMENT /* doubleType */
};
static int typeSizes[] = {
sizeof(int), /* intType */
sizeof(long), /* longType */
sizeof(voidPtr), /* ptrType */
sizeof(double) /* doubleType */
};
/*
* void marli(n)
*
* Description
*
* Test/example C function.
*
* Inputs
*
* n : number of times to emit message.
*
*/
void marli(n)
int n;
{
int i;
for (i = 0; i < n; i++) {
printf("Marli loves Steve!!!\n");
}
}
static int getErrno()
{
return (savedErrno);
}
#ifdef debugging /* Wed Nov 14 12:34:44 1990 */
/**/myioctl(fd, request, arg)
/**/int fd, request;
/**/char *arg;
/**/{
/**/ printf("fd %d request %x arg %x\n", fd, request, arg);
/**/ return (ioctl(fd, request, arg));
/**/}
#endif /* debugging Wed Nov 14 12:34:44 1990 */
/*
* static int my_putenv(str)
*
* Description
*
* Does a putenv library call. Exists because putenv (at least Sun's)
* expects that the string passed in will exist for the duration, and
* Smalltalk will free the string it passed to this this routine when
* control returns to it.
*
* Inputs
*
* str : String to stuff into the environment. Of the form name=value.
*
* Outputs
*
* Returned value from putenv() call.
*/
static int my_putenv(str)
char *str;
{
char *clone;
int len;
len = strlen(str) + 1; /* hold the null */
clone = (char *)malloc(len);
strcpy(clone, str);
return (putenv(clone));
}
static void testCallin(oop)
OOP oop;
{
strMsgSend(oop, "inspect", nil);
#ifdef preserved /* Tue Dec 31 21:55:47 1991 */
/**/ OOP o, sel;
/**/ double f;
/**/
/**/ sel = symbolToOOP("printNl");
/**/ o = msgSend(stringToOOP(msg), sel, nil);
/**/ strMsgSend(o, "inspect", nil);
/**/ strMsgSend(strMsgSend(o, ",", o, nil), "printNl", nil);
/**/ msgSendf(nil, "%s %s printNl", "this is a test");
/**/ msgSendf(&f, "%f %i + %f", 3, 4.7);
/**/ printf("result = %f\n", f);
#endif /* preserved Tue Dec 31 21:55:47 1991 */
}
void initCFuncs()
{
extern void marli(), windowLoop();
extern char *getAttrName();
extern voidPtr *getAttrValue();
extern void window_create();
extern int system();
extern char *getenv();
extern int read(), write(), open(), close(), ioctl(), lseek()/*, tell()*/;
defineCFunc("system", system);
defineCFunc("getenv", getenv);
defineCFunc("putenv", my_putenv);
defineCFunc("open", open);
defineCFunc("close", close);
defineCFunc("read", read);
defineCFunc("write", write);
/* defineCFunc("ioctl", myioctl); */
defineCFunc("ioctl", ioctl);
defineCFunc("lseek", lseek);
/* defineCFunc("tell", tell);*/
/* just to round out the set */
defineCFunc("readChar", readChar);
defineCFunc("readUChar", readUChar);
defineCFunc("readShort", readShort);
defineCFunc("readUShort", readUShort);
defineCFunc("readLong", readLong);
defineCFunc("readULong", readULong);
defineCFunc("readFloat", readFloat);
defineCFunc("readDouble", readDouble);
defineCFunc("writeChar", writeChar);
defineCFunc("writeShort", writeShort);
defineCFunc("writeLong", writeLong);
defineCFunc("writeFloat", writeFloat);
defineCFunc("writeDouble", writeDouble);
defineCFunc("getErrno", getErrno);
defineCFunc("testCallin", testCallin);
#ifdef DLD
initDldLib();
#endif
/* Non standard routines */
defineCFunc("marli", marli);
#ifdef SUN_WIN_HACKS
defineWindowFuncs();
#endif /* SUN_WIN_HACKS */
#ifdef notdefined
defineCFunc("getAttrName", getAttrName);
defineCFunc("getAttrValue", getAttrValue);
#endif
}
static OOP readChar(fd)
int fd;
{
char c;
if (read(fd, &c, sizeof(c)) != sizeof(c)) {
return (nilOOP);
}
return (charOOPAt(c));
}
static OOP readUChar(fd)
int fd;
{
unsigned char c;
if (read(fd, &c, sizeof(c)) != sizeof(c)) {
return (nilOOP);
}
return (charOOPAt(c));
}
static OOP readShort(fd)
int fd;
{
short s;
if (read(fd, &s, sizeof(s)) != sizeof(s)) {
return (nilOOP);
}
return (fromInt(s));
}
static OOP readUShort(fd)
int fd;
{
unsigned short s;
if (read(fd, &s, sizeof(s)) != sizeof(s)) {
return (nilOOP);
}
return (fromInt(s));
}
static OOP readLong(fd)
int fd;
{
long l;
if (read(fd, &l, sizeof(l)) != sizeof(l)) {
return (nilOOP);
}
return (fromInt(l));
}
static OOP readULong(fd)
int fd;
{
unsigned long l;
if (read(fd, &l, sizeof(l)) != sizeof(l)) {
return (nilOOP);
}
return (fromInt(l));
}
static OOP readFloat(fd)
int fd;
{
float f;
if (read(fd, &f, sizeof(f)) != sizeof(f)) {
return (nilOOP);
}
return (floatNew(f));
}
static OOP readDouble(fd)
int fd;
{
double d;
if (read(fd, &d, sizeof(d)) != sizeof(d)) {
return (nilOOP);
}
return (floatNew(d));
}
static void writeChar(fd, c)
int fd;
char c;
{
write(fd, &c, sizeof(c));
}
static void writeShort(fd, s)
int fd;
short s;
{
write(fd, &s, sizeof(s));
}
static void writeLong(fd, l)
int fd;
long l;
{
write(fd, &l, sizeof(l));
}
static void writeFloat(fd, f)
int fd;
float f;
{
write(fd, &f, sizeof(f));
}
static void writeDouble(fd, d)
int fd;
double d;
{
write(fd, &d, sizeof(d));
}
#ifdef DLD
/***********************************************************************
*
* GNU Dynamic Linking support code
*
***********************************************************************/
#include <dld.h>
char *dldArgv0;
static int getUndefinedSymCount()
{
return (dld_undefined_sym_count);
}
initDldLib()
{
if (dld_init (dld_find_executable (dldArgv0)) == 0) {
defineCFunc("dldLink", dld_link);
defineCFunc("dldUnlinkByFile", dld_unlink_by_file);
defineCFunc("dldUnlinkBySymbol", dld_unlink_by_symbol);
defineCFunc("dldGetSymbol", dld_get_symbol);
defineCFunc("dldGetFunc", dld_get_func);
defineCFunc("dldFunctionExecutableP", dld_function_executable_p);
defineCFunc("dldListUndefinedSym", dld_list_undefined_sym);
defineCFunc("dldCreateReference", dld_create_reference);
defineCFunc("dldDefineSym", dld_define_sym);
defineCFunc("dldRemoveDefinedSymbol", dld_remove_defined_symbol);
defineCFunc("getUndefinedSymCount", getUndefinedSymCount);
/* so user level code can invoke it! */
defineCFunc("defineCFunc", defineCFunc);
}
}
#endif
void defineCFunc(funcName, funcAddr)
char *funcName;
void (*funcAddr)();
{
cFuncIndex->funcName = funcName;
cFuncIndex->funcAddr = funcAddr;
cFuncIndex++;
}
void (*lookupFunction(funcName))()
char *funcName;
{
CFuncInfo *fip;
for (fip = cFuncInfo; fip < cFuncIndex; fip++) {
if (strcmp(funcName, fip->funcName) == 0) {
return (fip->funcAddr);
}
}
return (nil);
}
/*
* void invokeCRoutine(numArgs, methodOOP)
*
* Description
*
* Invokes a C routine. The Smalltalk arguments have been popped off the
* Smalltalk stack when this routine returns.
*
* Inputs
*
* numArgs:
*
* methodOOP:
*
*
*/
void invokeCRoutine(numArgs, methodOOP)
long numArgs;
OOP methodOOP;
{
CFuncDescriptor desc;
CDataType cType;
OOP oop; /* oopArgVec[32]; */
int i;
cArg = cArgVec;
desc = getCFuncDescriptor(methodOOP);
sip = stringInfo;
for (i = 0; i < numArgs; i++) {
oop = stackAt(numArgs - i - 1);
cType = getCType(desc, i);
pushSmalltalkObj(oop, cType);
}
popNOOPs(numArgs);
callCFunction(desc);
/* Fixup all returned string variables */
for ( ; sip-- != stringInfo; ) {
if (sip->returnedType == stringOutType) {
setOOPString(sip->stringOOP, sip->cString);
} else if (sip->returnedType == byteArrayOutType) {
setOOPBytes(sip->stringOOP, sip->cString);
}
free(sip->cString);
}
}
static CFuncDescriptor getCFuncDescriptor(methodOOP)
OOP methodOOP;
{
OOP associationOOP, descOOP;
associationOOP = methodLiteralExt(methodOOP, 0);
descOOP = associationValue(associationOOP);
return ((CFuncDescriptor)oopToObj(descOOP));
}
static CDataType getCType(desc, index)
CFuncDescriptor desc;
int index;
{
if (index < toInt(desc->numFixedArgs)) {
return ((CDataType)toInt(desc->argTypes[index]));
} else {
return (unknownType);
}
}
static void pushSmalltalkObj(oop, cType)
OOP oop;
CDataType cType;
{
OOP class;
int i;
CParamUnion u;
if (cArg - cArgVec >= ARG_VEC_SIZE) {
errorf("Attempt to push more than %d ints; extra parameters ignored",
ARG_VEC_SIZE);
return;
}
if (isInt(oop)) {
class = integerClass;
} else if (oop == trueOOP || oop == falseOOP) {
class = booleanClass;
} else {
class = oopClass(oop);
}
if (cType == smalltalkType) {
u.ptrVal = (voidPtr)oop;
registerOOP(oop); /* make sure it doesn't get gc'd */
pushObj(&u, ptrAlign);
} else if (class == integerClass) {
if (cType == longType || cType == unknownType) {
u.longVal = toInt(oop);
pushObj(&u, longAlign);
} else if (cType == intType || cType == charType) {
u.intVal = toInt(oop);
pushObj(&u, intAlign);
} else {
badType("Integer", cType);
}
} else if (class == booleanClass) {
if (cType == intType || cType == charType || cType == unknownType) {
u.intVal = (oop == trueOOP);
pushObj(&u, intAlign);
} else if (cType == longType) {
u.longVal = (oop == trueOOP);
pushObj(&u, longAlign);
} else {
badType("Boolean", cType);
}
} else if (class == charClass) {
if (cType == charType || cType == unknownType) {
u.intVal = charOOPValue(oop);
pushObj(&u, intAlign);
} else {
badType("Character", cType);
}
} else if (class == stringClass) {
if (cType == stringType || cType == stringOutType
|| cType == unknownType) {
if (sip - stringInfo >= ARG_VEC_SIZE) {
errorf("Too many string arguments, max is %d. Extra ignored",
ARG_VEC_SIZE);
}
sip->cString = toCString(oop);
u.ptrVal = (voidPtr)sip->cString;
sip->stringOOP = oop;
sip->returnedType = cType;
sip++;
pushObj(&u, ptrAlign);
} else {
badType("String", cType);
}
} else if (class == symbolClass) {
if (cType == symbolType || cType == stringType || cType == unknownType) {
if (sip - stringInfo >= ARG_VEC_SIZE) {
errorf("Too many string arguments, max is %d. Extra ignored",
ARG_VEC_SIZE);
}
sip->cString = toCString(oop);
u.ptrVal = (voidPtr)sip->cString;
sip->stringOOP = oop;
sip->returnedType = cType;
sip++;
pushObj(&u, ptrAlign);
} else {
badType("Symbol", cType);
}
} else if (class == byteArrayClass) {
if (cType == byteArrayType || cType == byteArrayOutType
|| cType == unknownType) {
if (sip - stringInfo >= ARG_VEC_SIZE) {
errorf("Too many string arguments, max is %d. Extra ignored",
ARG_VEC_SIZE);
}
sip->cString = toByteArray(oop);
u.ptrVal = (voidPtr)sip->cString;
sip->stringOOP = oop;
sip->returnedType = cType;
sip++;
pushObj(&u, ptrAlign);
} else {
badType("ByteArray", cType);
}
} else if (class == floatClass) {
if (cType == doubleType || cType == unknownType) {
u.doubleVal = floatOOPValue(oop);
pushObj(&u, doubleAlign);
} else {
badType("Float", cType);
}
} else if (class == cObjectClass) {
if (cType == cObjectType || cType == unknownType) {
u.ptrVal = cObjectValue(oop);
pushObj(&u, ptrAlign);
} else {
badType("CObject", cType);
}
} else if ((cType == cObjectType || cType == unknownType)
&& isAKindOf(class, cObjectClass)) {
u.ptrVal = cObjectValue(oop);
pushObj(&u, ptrAlign);
} else if (class == undefinedObjectClass) { /* how to encode nil */
switch (cType) {
case cObjectType:
case stringType:
case symbolType:
case unknownType:
u.ptrVal = nil;
pushObj(&u, ptrAlign);
break;
default:
badType("UndefinedObject", cType);
}
} else if (class == arrayClass) {
for (i = 1; i <= numOOPs(oopToObj(oop)); i++) {
pushSmalltalkObj(arrayAt(oop, i), unknownType);
}
}
}
static void pushObj(up, align)
CParamUnion *up;
AlignmentType align;
{
int i, alignInts;
alignInts = alignments[ENUM_INT(align)] / sizeof(int);
/* Align the stack properly */
if ((cArg - cArgVec) % alignInts) {
cArg += alignInts - ((cArg - cArgVec) % alignInts);
}
for (i = 0; i < typeSizes[ENUM_INT(align)] / sizeof(int); i++) {
if (cArg - cArgVec >= ARG_VEC_SIZE) {
errorf("Too many parameters, max = %d. Extra parameters ignored",
ARG_VEC_SIZE);
return;
}
*cArg++ = up->valueVec[i];
}
}
static void callCFunction(desc)
CFuncDescriptor desc;
{
int intResult;
long longResult;
double doubleResult;
int (*cFunction)();
CDataType returnType;
OOP returnTypeOOP;
cFunction = (int (*)())cObjectValue(desc->cFunction);
if (isInt(desc->returnType)) {
returnType = (CDataType)toInt(desc->returnType);
returnTypeOOP = nil;
} else {
returnTypeOOP = desc->returnType;
returnType = cObjectType;
}
switch (returnType) {
case voidType:
(*cFunction)(
cArgVec[0], cArgVec[1], cArgVec[2], cArgVec[3],
cArgVec[4], cArgVec[5], cArgVec[6], cArgVec[7],
cArgVec[8], cArgVec[9], cArgVec[10], cArgVec[11],
cArgVec[12], cArgVec[13], cArgVec[14], cArgVec[15],
cArgVec[16], cArgVec[17], cArgVec[18], cArgVec[19]);
break;
case charType:
case intType:
intResult = (*cFunction)(
cArgVec[0], cArgVec[1], cArgVec[2], cArgVec[3],
cArgVec[4], cArgVec[5], cArgVec[6], cArgVec[7],
cArgVec[8], cArgVec[9], cArgVec[10], cArgVec[11],
cArgVec[12], cArgVec[13], cArgVec[14], cArgVec[15],
cArgVec[16], cArgVec[17], cArgVec[18], cArgVec[19]);
switch (returnType) {
case intType:
setStackTop(fromInt((long)intResult));
break;
case charType:
setStackTop(charOOPAt((Byte)intResult));
break;
}
break;
case longType:
case stringType:
case symbolType:
case cObjectType:
case smalltalkType:
longResult = (*(long (*)())cFunction)(
cArgVec[0], cArgVec[1], cArgVec[2], cArgVec[3],
cArgVec[4], cArgVec[5], cArgVec[6], cArgVec[7],
cArgVec[8], cArgVec[9], cArgVec[10], cArgVec[11],
cArgVec[12], cArgVec[13], cArgVec[14], cArgVec[15],
cArgVec[16], cArgVec[17], cArgVec[18], cArgVec[19]);
switch (returnType) {
case longType:
setStackTop(fromInt(longResult));
break;
case stringType:
if (longResult == 0) {
setStackTop(nilOOP);
} else {
setStackTop(stringNew((char *)longResult));
}
break;
case symbolType:
if (longResult == 0) {
setStackTop(nilOOP);
} else {
setStackTop(internString((char *)longResult));
}
break;
case cObjectType:
if (longResult == 0) {
setStackTop(nilOOP);
} else {
if (returnTypeOOP) {
setStackTop(cObjectNewTyped((voidPtr)longResult, returnTypeOOP));
} else {
setStackTop(cObjectNew((voidPtr)longResult));
}
}
break;
case smalltalkType:
setStackTop((OOP)longResult);
break;
}
break;
case doubleType:
doubleResult = (*(double (*)())cFunction)(
cArgVec[0], cArgVec[1], cArgVec[2], cArgVec[3],
cArgVec[4], cArgVec[5], cArgVec[6], cArgVec[7],
cArgVec[8], cArgVec[9], cArgVec[10], cArgVec[11],
cArgVec[12], cArgVec[13], cArgVec[14], cArgVec[15],
cArgVec[16], cArgVec[17], cArgVec[18], cArgVec[19]);
setStackTop(floatNew(doubleResult));
break;
default:
errorf("Invalid C function return type specified, index %d\n",
returnType);
break;
}
savedErrno = errno;
}
static void badType(smalltalkTypeName, cType)
char *smalltalkTypeName;
CDataType cType;
{
errorf("Attempt to pass a %s as a %s", smalltalkTypeName,
cTypeName[ENUM_INT(cType)]);
}
OOP makeDescriptor(funcNameOOP, returnTypeOOP, argsOOP)
OOP funcNameOOP, returnTypeOOP, argsOOP;
{
char *funcName;
void (*funcAddr)();
int numArgs, i;
CFuncDescriptor desc;
funcName = (char *)toCString(funcNameOOP);
funcAddr = lookupFunction(funcName);
if (argsOOP == nilOOP) {
numArgs = 0;
} else {
numArgs = numOOPs(oopToObj(argsOOP));
}
/*
* since these are all either ints or new objects, I'm not moving the
* oops
*/
desc = (CFuncDescriptor)newInstanceWith(cFuncDescriptorClass, numArgs);
desc->cFunction = cObjectNew(funcAddr);
desc->cFunctionName = stringNew(funcName);
desc->numFixedArgs = fromInt(numArgs);
desc->returnType = classifyTypeSymbol(returnTypeOOP, true);
for (i = 1; i <= numArgs; i++) {
desc->argTypes[i - 1] = classifyTypeSymbol(arrayAt(argsOOP, i), false);
}
return (allocOOP(desc));
}
static OOP classifyTypeSymbol(symbolOOP, isReturn)
OOP symbolOOP;
Boolean isReturn;
{
SymbolTypeMap *sp;
Byte *symbolName;
for (sp = symbolTypeMap; sp->symbol != nil; sp++) {
if (*sp->symbol == symbolOOP) {
return (fromInt(sp->type));
}
}
if (isReturn) {
if (isClass(symbolOOP, cTypeClass)) {
return (symbolOOP); /* this is the type we want! */
}
}
symbolName = toCString(symbolOOP); /* yeah yeah...but they have the same
representation! */
errorf("Unknown data type symbol: %s", symbolName);
return (fromInt(unknownType));
}
/*
* void restoreCFuncDescriptor(cFuncDescOOP)
*
* Description
*
* This routine is called during image loading to restore a C function
* descriptor pointer. This is because between the time that the image
* was made and now, the executable image may have changed, so any
* reference to the C function address may be invalid. We therefore just
* perform the function lookup again and use that value.
*
* Inputs
*
* cFuncDescOOP:
* A C function descriptor object to be adjusted. Contains the
* name of the function to be looked up.
*
*/
void restoreCFuncDescriptor(cFuncDescOOP)
OOP cFuncDescOOP;
{
CFuncDescriptor desc;
void (*funcAddr)();
char *funcName;
desc = (CFuncDescriptor)oopToObj(cFuncDescOOP);
funcName = (char *)toCString(desc->cFunctionName);
funcAddr = lookupFunction(funcName);
setCObjectValue(desc->cFunction, funcAddr);
}
/***********************************************************************
*
* Call-in support code
*
***********************************************************************/
#ifdef not_working_yet
send(receiver, selectorStr, arg1, arg2, arg3, arg4, arg5, arg6, arg7,
arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17,
arg18, arg19, arg20)
OOP receiver, selector;
OOP arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12,
arg13, arg14, arg15, arg16, arg17, arg18, arg19, arg20;
{
}
OOP newIntObject(i)
long i;
{
return (fromInt(i));
}
OOP newCharObject(c)
Byte c;
{
return (charOOPAt(c));
}
OOP newFloatObject(f)
double f;
{
OOP oop;
oop = floatNew(f);
registerOOP(oop);
return (oop);
}
??? Want byte array types ???
OOP newStringObject(str)
char *str;
{
OOP oop;
if (str == nil) {
return (nilOOP);
} else {
oop = stringNew(str);
registerOOP(oop);
return (oop);
}
}
OOP newSymbolObject(str)
char *str;
{
OOP oop;
if (str == nil) {
return (nilOOP);
} else {
oop = internString(str);
return (oop);
}
}
OOP newCObject(cObject)
voidPtr cObject;
{
OOP oop;
if (cObject == nil) {
return (nilOOP);
} else {
oop = cObjectNew(cObject);
registerOOP(oop);
return (oop);
}
}
objectType(oop)
returns the type of an object, an enum, or unknown
need back conversion routines
void freeObject(oop)
OOP oop;
{
printf("!!! IMPLEMENT freeObject\n");
}
static void registerOOP(oop)
OOP oop;
{
printf("!!! IMPLEMENT registerOOP\n");
}
#endif /* not_done_yet */